﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.Collections;
using System.Diagnostics;
using Winforms = System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Xml.Serialization;

namespace WebReader
{
    
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class HabrWindow : Window
    {

       
        //download & pars
        private string adress = "http://habrahabr.ru/posts/collective/"; //"http://habrahabr.ru/posts/top/";
        private string adress_1 = "http://habrahabr.ru/posts/collective/page2/";
        public string loadedText = "";

        ArrayList arrLinks = new ArrayList();
       
        ArrayList arrLinksNew = new ArrayList();
        public Articles articles = new Articles();
        Articles articlesCurr = new Articles();
        string xmlName = "\\habr_Articles.xml";

        public string strKey = "post_title";
        Settings s;
        Winforms.FolderBrowserDialog fDial = new Winforms.FolderBrowserDialog();
       //save page
        string[] arrToParse = { ".css\"", ".js\"" };
        string siteText = "";
        string addressSite = "";
        string linkSelected = "";
        WebClient wcl;
        Winforms.Timer tmLink = new Winforms.Timer();
        Winforms.Timer tmAbort = new Winforms.Timer();
        Hyperlink hlCurr;
        int hintCurr = 0;
        string filePath = "";


        public int runCycle = 0;
       

        public HabrWindow(ref Settings _s, string _filePath)
        {
            s = _s;
            filePath = _filePath;
            InitializeComponent();
            FuncDownLoadText();
            SetTimerAbort();
            FuncFillLinksHabr();           
          
            SetTimer();
           
        }

        public void DgDownLoadText(Object myObject, EventArgs myEventArgs)
        {
            ThreadPool.QueueUserWorkItem(DownLoadText);
        }

        public void DownLoadText(Object myObject)
        {
            FuncDownLoadText();
        }

        public void FuncDownLoadText()
        {
            try
            {
                WebClient wc = new WebClient();
                string str = Encoding.UTF8.GetString(wc.DownloadData(adress));
                str += Encoding.UTF8.GetString(wc.DownloadData(adress_1));
                if (str != "") { loadedText = str; }
            }
            catch
            {
            }
        }   


     
        public void SetTimer()
        {
            Winforms.Timer tm = new Winforms.Timer();
            tm.Interval = 610000;
            tm.Tick += new EventHandler(FillLinksHabr);
            tm.Start();
            Winforms.Timer tmText = new Winforms.Timer();
            tmText.Interval = 510000;
            tmText.Tick += new EventHandler(DgDownLoadText);
            tmText.Start();
        }

        public void FillLinksHabr(Object myObject, EventArgs myEventArgs)
        {
            arrLinksNew.Clear();

            SetTimerAbort();

            FuncFillLinksHabr();
        }

        public void TurnAbort(Object myObject, EventArgs myEventArgs)
        {
            runCycle = 0;
            tmAbort.Stop();
        }

        public void FuncFillLinksHabr()
        {
            DeSerial();
            try
            {


                if (loadedText != "")
                {
                    articlesCurr.articles.Clear();
                    string text = loadedText;
                    tbMain.Inlines.Clear();
                    int numCurr = 0;
                    int num = 0;
                    int counter = 0;
                    while ((num = text.IndexOf(strKey, numCurr)) > 0 && runCycle == 1)
                    {

                        int numLink = 0;
                        int count = 0;
                        int startInd = num;
                        while ((numLink = text.IndexOf("href", startInd, count)) == -1)
                        {
                            startInd--;
                            count = num - startInd;
                        }

                        int numLinkEnd = text.IndexOf("\"", startInd + 7);
                        string name = "";
                        string link = "";
                        link = text.Substring(numLink + 6, (numLinkEnd - numLink - 6));
                        numLink = numLinkEnd;
                        numLink = text.IndexOf(">", numLinkEnd + 1);
                        numLinkEnd = text.IndexOf("<", numLink);
                        name = text.Substring(numLink + 1, (numLinkEnd - numLink - 1));

                        string nameHub = "";
                        int numHubName = 0;
                        int numHubsNameEnd = 0;
                        int numHubsEnd = 0;
                        numHubsEnd = text.IndexOf("</div>", numLinkEnd);
                        int numHubsCurr = 0;
                        numHubsCurr = numLinkEnd;

                        while(numHubsCurr < numHubsEnd)
                        {
                            if (nameHub != "")
                                { nameHub += "/ "; }
                            numHubsCurr = text.IndexOf("hub ", numHubsCurr);
                            numHubName = text.IndexOf(">", numHubsCurr);
                            numHubsNameEnd = text.IndexOf("<", numHubName);

                            if (numHubsNameEnd < numHubsEnd)
                            {
                                nameHub += text.Substring(numHubName + 1, (numHubsNameEnd - numHubName - 1));
                                numHubsCurr = numHubsNameEnd;
                                
                            }
                            
                        }                     




                        if (name != "" && !arrLinksNew.Contains(link))
                        {
                            AddLink(link, name, nameHub);
                            numCurr = numLinkEnd;
                            counter++;
                        }
                        if (counter > 9)
                        {
                            articles = articlesCurr;
                            Serial();
                            ChangeViewLinks();
                            return;
                        }

                        num = 0;
                    }
                }
            }
            catch
            {
            }
           
        }

        public void hl_lostFocus(object sender, MouseEventArgs e)
        {

            tmLink.Stop();         


        }
        public void hl_getFocus(object sender, MouseEventArgs e)
        {

            hlCurr = (Hyperlink)sender;
            for (int i = arrLinksNew.Count - 1; i >= 0; i--)
            {

                if ((arrLinksNew[i] as Hyperlink).NavigateUri == hlCurr.NavigateUri)
                {
                    hintCurr = i;
                    break;
                }

            }



            SetTimerColor();
        }

       
        public void AddLink(string link, string name, string nameHub)
        {
            ContextMenu menu = new System.Windows.Controls.ContextMenu();
            MenuItem item = new MenuItem();
            //item.Command = ApplicationCommands.Properties;
          
            item.Header = "Сохранить";
            item.Click += item_CLick;

            menu.Items.Add(item);
        

            Link lk = new Link();
            lk.strLink =  link;
           
            lk.strName = name;
            item.CommandParameter = link;

            lk.isRead = false;
            foreach (Link i in articles.articles)
            {
                if (lk.strName == i.strName && i.isRead == true)
                {
                    lk.isRead = true;
                    break;
                }
            }
                articlesCurr.articles.Add(lk);
            //arrLinks.Add(lk);
            Run rn = new Run(lk.strName);
            Hyperlink hl = new Hyperlink(rn);
            hl.FontSize = 12.0;
            hl.Click += hl_Click;
            hl.MouseLeave += hl_lostFocus;
            hl.MouseEnter += hl_getFocus;
            Uri ur = new Uri(link);
            hl.ContextMenu = menu;
            hl.NavigateUri = ur;
            hl.TextDecorations = new TextDecorationCollection();

            hl.ToolTip = nameHub + " \r\n " + name;
            if (lk.isRead == true)
            {
                hl.Foreground = Brushes.Black;
            }
            else
            {
                hl.Foreground = Brushes.Azure;
            }
            arrLinksNew.Add(hl);
           
        }
        public void ChangeViewLinks()
        {
            tbMain.Inlines.Clear();
            for (int i = 0; i < arrLinksNew.Count; i++)
            {
                tbMain.Inlines.Add((Hyperlink)arrLinksNew[i]);
                tbMain.Inlines.Add("\n");
            }


        }
        public void item_CLick(object sender, RoutedEventArgs e)
        {
            linkSelected = (sender as MenuItem).CommandParameter.ToString();
          
            

            if ((Winforms.DialogResult)fDial.ShowDialog() == Winforms.DialogResult.OK)
            {
                wcl = new WebClient();
                Encoding enc = wcl.Encoding;
                //wc.DownloadFile(tbLink.Text, tbFolder.Text + "/newSite.html");
                using (FileStream fs = new FileStream(fDial.SelectedPath + "/default.html", FileMode.Create))
                {
                    StreamWriter sw = new StreamWriter(fs);

                    //byte[] b = Encoding.Convert(enc, Encoding.UTF8, (wcl.DownloadData(linkSelected)));

                    siteText = Encoding.UTF8.GetString(wcl.DownloadData(linkSelected));
                    siteText = siteText.Replace("\"/", "\"");
                    sw.Write(siteText);
                    sw.Close();
                    fs.Dispose();
                }
                wcl.Dispose();
                parseNameSite();
                for (int i = 0; i < arrToParse.Length; i++)
                {
                    parseString(arrToParse[i].ToString(), fDial.SelectedPath);
                }
            }

            MessageBox.Show("Статья сохранена");
        }

        public void hl_Click(object sender, RoutedEventArgs e)
        {
            Process.Start((sender as Hyperlink).NavigateUri.ToString());
        }
        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
                DragMove();
        }
        private void Window_MouseEnter(object sender, MouseEventArgs e)
        {

            brdMain.Background = new LinearGradientBrush(Color.FromArgb(255, 146, 145, 145), Color.FromArgb(255, 145, 145, 145), 90);
        }

        private void Window_MouseLeave(object sender, MouseEventArgs e)
        {
            brdMain.Background = new LinearGradientBrush(Color.FromArgb(130, 255, 255, 255), Color.FromArgb(130, 0, 0, 0), 90);
        }

        private void HabrReader_MouseMove(object sender, MouseEventArgs e)
        {
            s.FillCoordHabr(Convert.ToInt32(HabrReader.Left), Convert.ToInt32(HabrReader.Top));
        }
       
       

        public void parseString(string strToParse, string _Path)
        {
            bool isNExt = true;
            int indexStart = 0;
            int i = 0;
            int n = 0;
            while (isNExt)
            {
                try
                {
                    i = siteText.IndexOf(strToParse, indexStart);
                    n = i;

                    while (siteText[n].ToString() != "\"")
                    {
                        n--;
                    }

                    string strTemp = siteText.Substring(n + 1, i - n + strToParse.Length - 2);
                    // string s = tbFolder.Text + strTemp.Replace("/", "\\");
                    string[] path = strTemp.Split(new char[] { '/' });
                    string pathResult = "";
                    for (int k = 0; k < path.Length - 1; k++)
                    {
                        pathResult += "\\" + path[k].ToString();
                    }
                    pathResult = _Path + pathResult;
                    Directory.CreateDirectory(pathResult);

                    wcl.DownloadFile(addressSite + "/" + strTemp, pathResult + "\\" + path[path.Length - 1].ToString());
                    indexStart = i + strToParse.Length + 1;
                }
                catch
                {

                    isNExt = false;
                }

            }

        }

        public void parseNameSite()
        {
            int m = linkSelected.IndexOf("/", 8);
            addressSite = linkSelected.Remove(m);

        }

        public void SetTimerAbort()
        {
            tmAbort.Interval = 120000;
            tmAbort.Tick += new EventHandler(TurnAbort);
            tmAbort.Start();
            runCycle = 1;
        }

        public void SetTimerColor()
        {
            tmLink.Interval = 300;
            tmLink.Tick += new EventHandler(ChangeColorLink);
            tmLink.Start();
        }
        public void FuncChangeColorLink()
        {
            Hyperlink l = (Hyperlink)arrLinksNew[hintCurr];
            l.Foreground = Brushes.Black;
            foreach (Link item in articles.articles)
            {
                if (item.strLink == l.NavigateUri.ToString())
                {
                    item.isRead = true;
                }
            }

            Serial();
        }
        public void ChangeColorLink(Object myObject, EventArgs myEventArgs)
        {
            FuncChangeColorLink();
        }


        /// <summary>
        /// записывание статей в файл
        /// </summary>
        public void Serial()
        {
            XmlHelper.Serial(filePath, xmlName, ref articles);

        }

        /// <summary>
        /// чтение статей из файла
        /// </summary>
        public void DeSerial()
        {

            XmlHelper.DeSerial(filePath, xmlName, ref articles);
        } 
    }
}
